import { RoomTypeEnum } from './const'
import dayjs from 'dayjs'
import Vue from 'vue'

let util = {}

if (process.env.NODE_ENV === 'development') {
  util.isDebug = true
} else {
  util.isDebug = false
}

util.title = function (title) {
  title = title || '云丁智能设备管理系统'
  window.document.title = title
}

/**
 * 获得字符串实际长度（中文2，英文1）
 * @param {String} str 字符串
 */
util.calcTextLen = function (str) {
  return str.replace(/[\u0391-\uFFE5]/g, 'aa').length // 先把中文替换成两个字节的英文，在计算长度
}

/**
* 按照名字进行字典序排序
*/
util.sortByName = function () {
  return function (a, b) {
    if (
      a.room_name &&
            b.room_name &&
            typeof a.room_name === 'string' &&
            typeof b.room_name === 'string'
    ) {
      return a.room_name.toUpperCase() <
                b.room_name.toUpperCase()
        ? -1
        : 1
    } else {
      return 0
    }
  }
}

/**
 * 深度普复制对象
 * @param {Object} obj 对象
 */
util.deepNormalCopy = function (obj) {
  if (typeof obj !== 'object') {
    return
  }
  let str = JSON.stringify(obj)
  return JSON.parse(str)
}

/**
 * @param {Function} fn 回调函数
 * @param {Number} delay 防抖时间
 */
util.debounce = function (fn, delay = 300) {
  let Timer

  return function () {
    let _this = this
    if (Timer) {
      clearTimeout(Timer)
    }
    Timer = setTimeout(() => {
      Timer = null
      fn.call(_this, ...arguments)
    }, delay)
  }
}

/**
 * @param {Function} fn 回调函数
 * @param {Number} delay 节流时间
 */
util.throttle = function (fn, delay = 600) {
  let startTime = new Date()

  return function () {
    let currentTime = new Date()
    let _this = this

    if (currentTime - startTime >= delay) {
      fn.call(_this, ...arguments)
      startTime = currentTime
    }
  }
}

/**
 * 补零
 * @param {Number} num 数字
 * @param {Number} totalLen 总长度
 */
util.fillZero = function (num, totalLen) {
  return (Array(totalLen).join(0) + num).slice(-totalLen)
}

/**
 * 打印日志
 * @param {Array} rest 参数数组
 */
util.log = function (...rest) {
  if (!util.isDebug) {
    return
  }

  let d = new Date()
  let dStr =
        '[' +
        // + d.getFullYear() + '-'
        util.fillZero(d.getMonth() + 1, 2) +
        '-' +
        util.fillZero(d.getDate(), 2) +
        ' ' +
        util.fillZero(d.getHours(), 2) +
        ':' +
        util.fillZero(d.getMinutes(), 2) +
        ':' +
        util.fillZero(d.getSeconds(), 2) +
        '.' +
        util.fillZero(d.getMilliseconds(), 2) +
        ']'

  rest.unshift(dStr, location.hash)
  // console.debug.apply(console, rest);
  console.log.apply(console, JSON.parse(JSON.stringify(rest)))
}

util.inOf = function (arr, targetArr) {
  let res = true
  arr.forEach(item => {
    if (targetArr.indexOf(item) < 0) {
      res = false
    }
  })
  return res
}

util.oneOf = function (ele, targetArr) {
  if (targetArr.indexOf(ele) >= 0) {
    return true
  } else {
    return false
  }
}

util.showThisRoute = function (itAccess, currentAccess) {
  if (typeof itAccess === 'object' && Array.isArray(itAccess)) {
    return util.oneOf(currentAccess, itAccess)
  } else {
    return itAccess === currentAccess
  }
}

util.getRouterObjByName = function (routers, name) {
  if (!name || !routers || !routers.length) {
    return null
  }
  // debugger;
  let routerObj = null
  for (let item of routers) {
    if (item.name === name) {
      return item
    }
    routerObj = util.getRouterObjByName(item.children, name)
    if (routerObj) {
      return routerObj
    }
  }
  return null
}

util.handleTitle = function (vm, item) {
  if (typeof item.title === 'object') {
    return vm.$t(item.title.i18n)
  } else {
    return item.title
  }
}

util.openNewPage = function (vm, name, argu, query) {
  let pageOpenedList = vm.$store.state.app.pageOpenedList
  let openedPageLen = pageOpenedList.length
  let i = 0
  let tagHasOpened = false
  while (i < openedPageLen) {
    if (name === pageOpenedList[i].name) {
      // 页面已经打开
      vm.$store.commit('pageOpenedList', {
        index: i,
        argu: argu,
        query: query
      })
      tagHasOpened = true
      break
    }
    i++
  }
  if (!tagHasOpened) {
    let tag = vm.$store.state.app.tagsList.filter(item => {
      if (item.children) {
        return name === item.children[0].name
      } else {
        return name === item.name
      }
    })
    tag = tag[0]
    if (tag) {
      tag = tag.children ? tag.children[0] : tag
      if (argu) {
        tag.argu = argu
      }
      if (query) {
        tag.query = query
      }
      vm.$store.commit('increateTag', tag)
    }
  }
  vm.$store.commit('setCurrentPageName', name)
}

// 获取密码状态
util.getPasswordStatus = function (status) {
  const state = Number(status) // 状态, 容错，可能是string或者number

  if (state > 5 || state < 0) {
    return '未知'
  }

  return ['未设置', '不可用', '已生效', '将生效', '已过期', '已冻结'][state]
}

util.toDefaultPage = function (routers, name, route, next) {
  let len = routers.length
  let i = 0
  let notHandle = true
  while (i < len) {
    if (routers[i].name === name && routers[i].children && routers[i].redirect === undefined) {
      route.replace({
        name: routers[i].children[0].name
      })
      notHandle = false
      next()
      break
    }
    i++
  }
  if (notHandle) {
    next()
  }
}

util.dataURLtoBlob = function (dataurl) {
  let arr = dataurl.split(',')
  let mime = arr[0].match(/:(.*?);/)[1]
  let bstr = atob(arr[1])
  let n = bstr.length
  let u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
}

util.isArray = function (value) {
  return Object.prototype.toString.call(value) === '[object Array]'
}

// 剩余电量
util.getLeftElectric = function (date) {
  // return ( Number(date.electric_amount) - Number(date.electric_read) ).toFixed(2)
  return (Number(date.electric_amount) - Number(date.electric_read) + Number(date.pool_amount) - Number(date.pool_read)).toFixed(2)
}

/**
 * 返回房间名
 * @param {Object} room 房间数据
 */
util.getRoomName = function (room) {
  if (room.room_type === RoomTypeEnum.PUBLIC) {
    if (!room.parent_ids || !room.parent_ids.length) {
      return '公区'
    }
    return room.room_name + '公区'
  }
  return room.room_name
}

/**
 * 连接省市区等地址信息
 * @param {province, city, district, address} location 接口返回的地址对象
 * @param {*} deep 显示的地址深度
 * @param {*} split 各个字段的连接符
 */
util.concatLocation = function (location, deep = 4, split = ' ') {
  let result = ''
  let count = deep
  const keys = ['province', 'city', 'district', 'address']
  while (count > 0) {
    if (count === deep) {
      // 如果省和城市相同, 不需要省
      result += location[keys.shift()] || ''
      if (location.province === location.city) {
        keys.shift()
        count--
      }
    } else {
      result += split + (location[keys.shift()] || '')
    }
    count--
  }
  return result
}
util.concatAddress = util.concatLocation

/**
 * 清除对象false值
 * @param {object} obj 目标对象
 * @param {array} except false值数组, 不清除该这些false值
 * @param {array} include 任意值数组, 清除包含这些值的值
 * return Object
 */
util.cleanObj = function cleanObj (obj, except = [], include = []) {
  const result = Object.create(null)
  for (let i in obj) {
    const value = obj[i]
    if (JSON.stringify(value) === '[]') continue
    if (value !== null && Object.prototype.toString.call(value) === '[object Object]') {
      result[i] = cleanObj(value, except, include)
    } else {
      if (value && !include.includes(value)) {
        result[i] = obj[i]
      }
      if (except.includes(value)) {
        result[i] = value
      }
    }
  }
  return result
}

util.formErrorHandler = function (rules, once = false) {
  const errors = []
  rules.forEach(rule => {
    if (rule.valid) {
      errors.push(rule.msg)
    }
  })
  if (errors.length) {
    errors.forEach((err, index) => {
      if (once && index > 0) return
      Vue.prototype.$Message.error(err)
    })
    return true
  }
  return false
}

/**
* @param {Array} arg 不展示的sn model字段数组
*/
util.someThingShowInSpecialModel = (sn, ...sn_model_arr) => {
  const isShow = () => {
    if (!sn) {
      return false
    } else {
      const model = sn.substring(6, 8)
      return !sn_model_arr.find((sn_model) => sn_model === model)
    }
  }

  return isShow
}

util.sn2model = param => {
  const sn = String(param)
    .trim()
    .toLowerCase()

    // 门锁
  if (sn.startsWith('lk') && sn.length === 20) {
    const lockType = sn.substring(6, 8)
    switch (lockType) {
      case '01':
        return {
          device: 'D1',
          id: 2
        }
      case '02':
        return {
          device: 'T1',
          id: 2
        }
      case '19':
        return {
          device: 'D2F',
          id: 2
        }
      case '23':
        return {
          device: 'T3',
          id: 2,
          SpecificModel: 'T3P'
        }
      case '24':
        return {
          device: 'T3',
          id: 2,
          SpecificModel: 'T3'
        }
      case '25':
        return {
          device: 'T3',
          id: 2,
          SpecificModel: 'T3S'
        }
      case '26':
        return {
          device: 'D3',
          id: 2,
          SpecificModel: 'D3'
        }
      case '29':
        return {
          device: 'D3',
          id: 2,
          SpecificModel: 'D3S'
        }
      default:
        return {
          device: 'LOCK',
          id: 2
        }
    }
  }

  // 云丁网关
  if (sn.startsWith('cn') && sn.length === 20) {
    return {
      device: 'GATEWAY',
      id: 1
    }
  }

  // 华为网关
  const REG_HW = /^hw([0-9a-fA-F]{2})(([0-9a-fA-F]{2}){5})$/
  if (REG_HW.test(sn)) {
    return {
      device: 'GATEWAY_HUAWEI',
      id: 1
    }
  }

  // 中继器
  // if (sn.startsWith('rp') && sn.length === 20) {
  //     return {
  //         device: 'REPEATER',
  //         id: 8
  //     };
  // }

  // 电表采集器
  if (sn.startsWith('em') && sn.length === 20) {
    return {
      device: 'ELECOLLECTOR',
      id: 4
    }
  }

  // 水表网关
  if (sn.length === 12) {
    const waterGateway = sn.substring(4, 6)
    switch (waterGateway) {
      case '00':
        return {
          device: 'WM2-64',
          id: 5
        }
      case '01':
        return {
          device: 'WM2-128',
          id: 5
        }
      case '10':
        return {
          device: 'WM2-W',
          id: 5
        }
    }

    const elemeterType = sn.substring(6, 8)
    switch (elemeterType) {
      case '00':
        return {
          device: 'A1',
          id: 3
        }
      case '01':
        return {
          device: 'A2',
          id: 3
        }
      case '02':
        return {
          device: 'A3',
          id: 3
        }
      case '03':
        return {
          device: 'A1Z',
          id: 31
        }
      case '04':
        return {
          device: 'A1Z',
          id: 31
        }
      case '05':
        return {
          device: 'A45',
          id: 32
        }
      case '06':
        return {
          device: 'A43',
          id: 32
        }
      case '07':
        return {
          device: 'AMG1',
          id: 33
        }
      case '08':
        return {
          device: 'AMW1',
          id: 34
        }
      case '09':
        return {
          device: 'A1PZ',
          id: 31
        }
      case '10':
        return {
          device: 'A1P',
          id: 3
        }
      case '11':
        return {
          device: 'A4P5',
          id: 32
        }
      case '12':
        return {
          device: 'A4P3',
          id: 32
        }
      case '13':
        return {
          device: 'AMC1',
          id: 30
        }
      case '80':
        return {
          device: 'AT120',
          id: 3
        }
      default:
        return null
    }
  }

  if (sn.length === 10 && (sn[3] === '0' || sn[3] === '1')) {
    return {
      device: 'WATERMETER',
      id: 6
    }
  }

  if (sn.length === 8 && (sn[2] === '0' || sn[2] === '1')) {
    return {
      device: 'WATERMETER',
      id: 6
    }
  }

  // 人脸门禁
  if (sn.length === 13 && (sn.substring(0, 4) === 'cj6p' || sn.substring(0, 4) === 'cj6v')) {
    return {
      device: 'ACCESS_CONTROL',
      id: 10
    }
  }

  // M3门禁
  if (sn.startsWith('ec') && sn.length === 20 && sn.substring(6, 8) === '01') {
    return {
      device: 'M3_ACCESS',
      id: 11
    }
  }

  return null
}

// {online: 2, switch: 1, expired: false, low_power: false, low_amount: false, trans_error: false}
util.getDeviceExceptions = device => {
  const {
    online, switch: switchStatus, trans_error, low_amount, longtime_no_open, low_power, device_type
    // longtime_no_close, model, type 硬件支持不完全 2019-4-19
  } = device
  // const hasLongtimeNocloseLock = [ 'lk-25', 'lk-17', 'lk-18', 'T3S', 'T2S', 'D2S' ].some(modelType => [ type, model ].includes(modelType.toLowerCase()) || [ type, model ].includes(modelType.toUpperCase()));
  const rules = [{
    name: '离线',
    valid: online === 2
  }, {
    name: '低电',
    deviceType: [2],
    valid: low_power
  }, {
    name: '长时间未开门',
    deviceType: [2],
    valid: longtime_no_open
  }, {
    name: '跳闸',
    deviceType: [3],
    valid: switchStatus === 2
  }, {
    name: '接线异常',
    deviceType: [3, 6, 7],
    valid: online === 2 && trans_error // 设备在线不显示接线异常
  }, {
    name: '欠费',
    deviceType: [3],
    valid: low_amount
  }]
  // if (hasLongtimeNocloseLock) {
  //     rules.push({
  //         name: '未锁',
  //         deviceType: [2],
  //         valid: longtime_no_close
  //     });
  // }
  const errors = renderExceptionsNames(rules, device_type)
  return errors.join(' ')
}

function renderExceptionsNames (rules, device_type) {
  return rules.reduce((result, option) => {
    if (!option.deviceType || option.deviceType.includes(device_type)) {
      if (option.valid) {
        result.push(option.name)
      }
    }
    return result
  }, [])
}

util.startOfDay = (time, timestamp = true) => {
  const result = dayjs(time).startOf('day')
  return timestamp ? result.valueOf() : result
}

util.endOfDay = (time, timestamp = true) => {
  const result = dayjs(time).endOf('day')
  return timestamp ? result.valueOf() : result
}

util.lockSettingTranslate = (response) => {
  const { current, parent, defalut } = response
  const result = {
    model: (Object.keys(current).length === 0 || current.alarm_time === null) ? 'extend' : 'self' // 是否使用父级配置
  }
  const keys = ['enable_alarm', 'alarm_time', 'alarm_unlock', 'msg_notify', 'low_power', 'forbid_add_password', 'forbid_add_tmp_password']
  for (let i of keys) {
    if (current[i] !== undefined && current[i] !== null) {
      result[i] = current[i]
    } else {
      if (parent[i] !== undefined) {
        result[i] = parent[i]
      } else if (defalut[i] !== undefined) {
        result[i] = defalut[i]
      }
    }
  }
  return result
}

util.escapeHtml = (html) => {
  return html.replace(/</g, '&lt;').replace(/>/g, '"&gt;')
}

export default util
